package com.doublethread.easymart.modules.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.doublethread.easymart.common.exception.FileException;
import com.doublethread.easymart.common.exception.ProductException;
import com.doublethread.easymart.common.result.PageResult;
import com.doublethread.easymart.common.utils.Base64MultipartFile;
import com.doublethread.easymart.common.utils.OssUtils;
import com.doublethread.easymart.modules.product.dto.CategoryDTO;
import com.doublethread.easymart.modules.product.dto.CategoryQueryDTO;
import com.doublethread.easymart.modules.product.dto.CategoryUpdateStatusDTO;
import com.doublethread.easymart.modules.product.entity.Category;
import com.doublethread.easymart.modules.product.entity.Product;
import com.doublethread.easymart.modules.product.mapper.CategoryMapper;
import com.doublethread.easymart.modules.product.mapper.ProductMapper;
import com.doublethread.easymart.modules.product.service.CategoryService;
import com.doublethread.easymart.modules.product.vo.CategoryVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 商品分类服务实现类
 */
@Slf4j
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private OssUtils ossUtils;

    @Override
    public List<CategoryVO> getCategoryTree() {
        log.info("获取分类树");

        List<Category> categories = this.list(new LambdaQueryWrapper<Category>()
                .eq(Category::getStatus, 1)
                .orderByAsc(Category::getLevel, Category::getSortOrder));

        return categories.stream()
                .map(this::convertToCategoryVO)
                .toList();
    }

    @Override
    public List<CategoryVO> getFirstLevelCategories() {
        log.info("获取一级分类列表");

        List<Category> categories = this.list(new LambdaQueryWrapper<Category>()
                .eq(Category::getParentId, 0L)
                .eq(Category::getStatus, 1)
                .orderByAsc(Category::getSortOrder));

        return categories.stream()
                .map(this::convertToCategoryVO)
                .toList();
    }

    @Override
    public List<CategoryVO> getSubCategories(Long parentId) {
        log.info("获取子分类列表");

        List<Category> categories = this.list(new LambdaQueryWrapper<Category>()
                .eq(Category::getParentId, parentId)
                .eq(Category::getStatus, 1)
                .orderByAsc(Category::getSortOrder));

        return categories.stream()
                .map(this::convertToCategoryVO)
                .toList();
    }

    @Override
    public PageResult<CategoryVO> getCategoryList(CategoryQueryDTO queryDTO) {
        log.info("管理端查询分类列表");

        // 构建查询条件
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();

        // 层级筛选
        if (queryDTO.getLevel() != null) {
            queryWrapper.eq(Category::getLevel, queryDTO.getLevel());
        }

        // 状态筛选
        if (queryDTO.getStatus() != null) {
            queryWrapper.eq(Category::getStatus, queryDTO.getStatus());
        }

        // 父分类筛选
        if (queryDTO.getParentId() != null) {
            queryWrapper.eq(Category::getParentId, queryDTO.getParentId());
        }

        // 关键词搜索
        if (StringUtils.hasText(queryDTO.getKeyword())) {
            queryWrapper.like(Category::getName, queryDTO.getKeyword());
        }

        // 排序处理
        if ("sort_order".equals(queryDTO.getSortBy())) {
            if ("desc".equals(queryDTO.getSortOrder())) {
                queryWrapper.orderByDesc(Category::getSortOrder);
            } else {
                queryWrapper.orderByAsc(Category::getSortOrder);
            }
        } else if ("create_time".equals(queryDTO.getSortBy())) {
            if ("desc".equals(queryDTO.getSortOrder())) {
                queryWrapper.orderByDesc(Category::getCreateTime);
            } else {
                queryWrapper.orderByAsc(Category::getCreateTime);
            }
        } else if ("update_time".equals(queryDTO.getSortBy())) {
            if ("desc".equals(queryDTO.getSortOrder())) {
                queryWrapper.orderByDesc(Category::getUpdateTime);
            } else {
                queryWrapper.orderByAsc(Category::getUpdateTime);
            }
        } else {
            // 默认按排序值升序
            queryWrapper.orderByAsc(Category::getSortOrder);
        }

        // 分页查询
        Page<Category> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        Page<Category> categoryPage = this.page(page, queryWrapper);

        // 使用PageResult.of方法进行转换
        return PageResult.of(categoryPage, this::convertToCategoryVO);
    }

    @Override
    public CategoryVO getCategoryById(Long categoryId) {
        log.info("获取分类详情");

        Category category = this.getById(categoryId);
        if (category == null) {
            ProductException.categoryNotFound();
        }

        return convertToCategoryVO(category);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CategoryVO createCategory(CategoryDTO categoryDTO) {
        log.info("创建分类");

        // 检查分类名称是否已存在（同级分类下不能重名）
        checkCategoryNameExists(categoryDTO.getName(), categoryDTO.getParentId(), null);

        // 计算分类层级
        Integer level = calculateCategoryLevel(categoryDTO.getParentId());

        // 处理图标上传
        String finalIcon = categoryDTO.getIcon();
        if (finalIcon != null && finalIcon.startsWith("data:image/")) {
            log.info("上传图标");
            try {
                finalIcon = uploadCategoryIcon(finalIcon);
                log.info("图标上传成功");
            } catch (Exception e) {
                log.error("图标上传失败");
                FileException.uploadFailed();
            }
        }

        // 构建分类实体
        Category category = Category.builder()
                .name(categoryDTO.getName())
                .parentId(categoryDTO.getParentId())
                .level(level)
                .sortOrder(categoryDTO.getSortOrder())
                .icon(finalIcon)
                .description(categoryDTO.getDescription())
                .status(1) // 默认启用
                .build();

        // 保存分类
        this.save(category);

        log.info("分类创建成功");
        return convertToCategoryVO(category);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCategory(Long categoryId, CategoryDTO categoryDTO) {
        log.info("更新分类");

        // 检查分类是否存在
        Category existingCategory = this.getById(categoryId);
        if (existingCategory == null) {
            ProductException.categoryNotFound();
        }

        // 检查分类名称是否已存在（同级分类下不能重名）
        checkCategoryNameExists(categoryDTO.getName(), categoryDTO.getParentId(), categoryId);

        // 处理图标上传
        String finalIcon = categoryDTO.getIcon();
        String oldIcon = existingCategory.getIcon();
        if (finalIcon != null && finalIcon.startsWith("data:image/")) {
            log.info("上传图标");
            try {
                finalIcon = uploadCategoryIcon(finalIcon);
                log.info("图标上传成功");

                // 异步删除旧图标
                if (oldIcon != null && !oldIcon.isEmpty() && oldIcon.startsWith("http")) {
                    CompletableFuture.runAsync(() -> {
                        try {
                            ossUtils.deleteImage(oldIcon);
                            log.info("删除旧图标成功");
                        } catch (Exception e) {
                            log.warn("删除旧图标失败");
                        }
                    });
                }
            } catch (Exception e) {
                log.error("图标上传失败");
                FileException.uploadFailed();
            }
        }

        // 构建更新实体
        Category updateCategory = Category.builder()
                .id(categoryId)
                .name(categoryDTO.getName())
                .parentId(categoryDTO.getParentId())
                .level(calculateCategoryLevel(categoryDTO.getParentId()))
                .sortOrder(categoryDTO.getSortOrder())
                .icon(finalIcon)
                .description(categoryDTO.getDescription())
                .build();

        // 更新分类
        this.updateById(updateCategory);

        log.info("分类更新成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteCategory(Long categoryId) {
        log.info("删除分类");

        // 检查分类是否存在
        Category category = this.getById(categoryId);
        if (category == null) {
            ProductException.categoryNotFound();
        }

        // 检查是否有子分类
        long childCount = this.count(new LambdaQueryWrapper<Category>()
                .eq(Category::getParentId, categoryId));
        if (childCount > 0) {
            ProductException.categoryHasChildren();
        }

        // 检查是否有商品
        long productCount = getProductCountByCategory(categoryId);
        if (productCount > 0) {
            ProductException.categoryHasProducts();
        }

        // 使用MyBatis-Plus软删除
        this.removeById(categoryId);

        log.info("分类删除成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCategoryStatus(Long categoryId, CategoryUpdateStatusDTO statusDTO) {
        log.info("更新分类状态");

        // 检查分类是否存在
        Category category = this.getById(categoryId);
        if (category == null) {
            ProductException.categoryNotFound();
        }

        // 更新状态
        Category updateCategory = new Category();
        updateCategory.setId(categoryId);
        updateCategory.setStatus(statusDTO.getStatus());
        this.updateById(updateCategory);

        log.info("分类状态更新成功");
    }

    // ==================== 私有辅助方法 ====================

    /**
     * 检查分类名称是否已存在
     */
    private void checkCategoryNameExists(String name, Long parentId, Long excludeId) {
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<Category>()
                .eq(Category::getName, name)
                .eq(Category::getParentId, parentId);

        // 排除当前分类（用于更新时的检查）
        if (excludeId != null) {
            queryWrapper.ne(Category::getId, excludeId);
        }

        long count = this.count(queryWrapper);
        if (count > 0) {
            ProductException.categoryNameExists();
        }
    }

    /**
     * 计算分类层级
     */
    private Integer calculateCategoryLevel(Long parentId) {
        if (parentId == null || parentId.equals(0L)) {
            return 1; // 一级分类
        }

        Category parentCategory = this.getById(parentId);
        if (parentCategory == null) {
            ProductException.categoryNotFound();
            return null; // 这行代码不会执行，但避免编译器警告
        }

        return parentCategory.getLevel() + 1;
    }

    /**
     * 获取分类下的商品数量
     * 统计该分类下所有启用且未删除的商品数量
     */
    private Integer getProductCountByCategory(Long categoryId) {
        // 使用ProductMapper统计该分类下的商品数量
        Long count = productMapper.selectCount(new LambdaQueryWrapper<Product>()
                .eq(Product::getCategoryId, categoryId)
                .eq(Product::getStatus, 1)  // 只统计启用的商品
                .eq(Product::getIsDeleted, 0)); // 只统计未删除的商品

        return count.intValue();
    }

    /**
     * 转换Category实体为CategoryVO
     */
    private CategoryVO convertToCategoryVO(Category category) {
        // 获取父分类名称
        String parentName = null;
        if (category.getParentId() != null && !category.getParentId().equals(0L)) {
            Category parentCategory = this.getById(category.getParentId());
            if (parentCategory != null) {
                parentName = parentCategory.getName();
            }
        }

        return CategoryVO.builder()
                .id(category.getId())
                .name(category.getName())
                .parentId(category.getParentId())
                .parentName(parentName)
                .level(category.getLevel())
                .sortOrder(category.getSortOrder())
                .icon(category.getIcon())
                .description(category.getDescription())
                .status(category.getStatus())
                .productCount(getProductCountByCategory(category.getId()))
                .createTime(category.getCreateTime())
                .updateTime(category.getUpdateTime())
                .build();
    }

    @Override
    public String uploadCategoryIcon(String iconBase64) {
        // 分类图标上传路径常量
        final String CATEGORY_ICON_PATH = "images/category/";

        try {
            log.info("开始上传分类图标");

            // 1. 验证Base64数据格式
            if (iconBase64 == null || !iconBase64.startsWith("data:image/")) {
                log.error("分类图标数据格式不正确");
                FileException.typeNotAllowed();
            }

            // 2. 将Base64数据转换为MultipartFile
            MultipartFile iconFile = Base64MultipartFile.fromBase64(iconBase64);

            // 3. 验证图标文件大小（限制1MB）
            if (iconFile.getSize() > 1024 * 1024) {
                log.error("分类图标文件过大");
                FileException.sizeExceeded();
            }

            // 4. 使用OSS工具上传图标到指定路径
            String iconUrl = ossUtils.uploadImage(iconFile, CATEGORY_ICON_PATH);

            // 5. 验证上传结果
            if (iconUrl == null || iconUrl.isEmpty()) {
                log.error("OSS上传返回空URL");
                FileException.uploadFailed();
            }

            log.info("分类图标上传成功");
            return iconUrl;

        } catch (Exception e) {
            log.error("分类图标上传失败: error={}", e.getMessage(), e);
            // 重新抛出异常，不返回null
            if (e instanceof RuntimeException) {
                throw e;
            }
            FileException.uploadFailed();
            return null; // 这行不会执行，因为上面会抛异常
        }
    }
}
